//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name: strata.h

Date Created: 6/21/2002 

Abstract: Flash media driver (FMD) interface for Intel StrataFlash memory chips.

Functions: 

Notes: As noted, this media driver works on behalf of the FAL to directly
       access the underlying FLASH hardware.  Consquently, this module 
       needs to be linked with FAL.LIB to produce the device driver 
       named FLASHDRV.DLL.  It may also be used directly in a boot loader image.

--*/
#ifndef _STRATA_H_
#define _STRATA_H_

// Basic read/write macros.
#define WRITE_ULONG(ptr,ul)  WRITE_REGISTER_ULONG((PULONG)(ptr),ul)
#define READ_ULONG(ptr)      READ_REGISTER_ULONG((PULONG)(ptr))
#define WRITE_USHORT(ptr,us) WRITE_REGISTER_USHORT((PUSHORT)(ptr),us)
#define READ_USHORT(ptr)     READ_REGISTER_USHORT((PUSHORT)(ptr))

// Flash read/write macros.
// We assume the StrataFlash part is in 16-bit mode (as opposed to 8-bit mode).
#define WRITE_FLASH(ptr, val) (g_bPairedFlash ? WRITE_ULONG(ptr, (ULONG)val) : WRITE_USHORT(ptr, (USHORT)val))
#define READ_FLASH(ptr)       (g_bPairedFlash ? READ_ULONG(ptr) : READ_USHORT(ptr))
#define READ_FLASH_INDEXED(ptr, offset)       (g_bPairedFlash ? READ_ULONG((PULONG)ptr + offset) : READ_USHORT((PUSHORT)ptr + offset))
// Write a command to the flash part.
//#define WRITE_COMMAND(ptr, cmd) (g_bPairedFlash ? WRITE_ULONG(ptr, (ULONG)((cmd << 16) | cmd)) : WRITE_USHORT(ptr, (USHORT)cmd))
// Check for expected status.
#define CHECK_STATUS(ptr, stat) (g_bPairedFlash ? ((READ_ULONG(ptr) & ((stat << 16) | stat)) == ((stat << 16) | stat)) : ((READ_USHORT(ptr) & stat) == stat))
#define CHECK_STATUS_INDEXED(ptr, offset, stat) (g_bPairedFlash ? ((READ_ULONG((PULONG)ptr + offset) & ((stat << 16) | stat)) == ((stat << 16) | stat)) : ((READ_USHORT((PUSHORT)ptr + offset) & stat) == stat))
// Is specified address block-aligned?
#define IS_BLOCK_ALIGNED(ptr)   (((ULONG)ptr % g_FMDInfo.BlockSize) ? FALSE : TRUE)
#define CREATE_MASK(flag) (g_bPairedFlash ? ((flag << 16) | flag) : flag)
#define UPPER(flag) (flag << 16)


// We sign the last 32 bytes of each flash block so we can verify that the block
// is valid at boot time.  OEMs should feel free to modify gc_dwBlockSig
const DWORD gc_dwBlockSig[8] = {0xC1552106, 0xDF9C29D5, 0xBAB8EAB8, 0x82D3F9F3,
                                      0x3B438A47, 0xA9D92AE6, 0x09396731, 0x12BF6753};

#define BLOCK_SIG_BYTES    32
#define BLOCK_SIG_LOC(bs, bl)          (bs + bl - BLOCK_SIG_BYTES)


//
// Intel 28F320 flash commands and status definitions.
//
// Commands.
#define READ_QUERY_CMD			0x0098
#define READ_IDENT_CMD			0x0090
#define READ_ARRAY_CMD			0x00FF
#define BYTEWORD_PROGRAM_CMD    0x0040
#define CLEAR_STATUS_CMD        0x5050
#define READ_STATUS_CMD			0x7070
#define BLOCK_LOCK_CMD          0x0060
#define BLOCK_PROCEED_CMD		0x00D0
#define BLOCK_SETLOCK_CMD		0x0001
#define BLOCK_ERASE_CMD			0x0020
#define BUFFER_WRITE_CMD		0x00E8

// Status.
#define STATUS_ERROR_LOCKED     0x0002
#define STATUS_ERROR_VOLTAGE   0x0008
#define STATUS_ERROR_SR4           0x0010   // Can mean either erase or set lock bit error
#define STATUS_ERROR_SR5           0x0020   // Can mean either program or clear lock bit error
#define STATUS_ERROR_COMMAND 0x0030
#define STATUS_READY_MASK		0x0080

#define CHECK_STATUS_TIMEOUT  0xffffff

// Flash CFI query structure offsets.
#define QS_MFGCODE_OFFSET		0x0
#define QS_DEVCODE_OFFSET		0x1
#define QS_IDSTRING_OFFSET		0x10
#define QS_SYSINTF_OFFSET		0x1B
#define QS_DEVGEOM_OFFSET		0x27

#define REGION_SIZE_MULT		256
#define SECTOR_SIZE             512     // Number of data bytes in a sector

#define MFGCODE_INTEL           0x0089	// Intel's flash manufacturing code.

#define IDSTRING_Q				0x0051	// ASCII 'Q'.
#define IDSTRING_R				0x0052  // ASCII 'R'.
#define IDSTRING_Y				0x0059	// ASCII 'Y'.

#pragma pack(1)
// Flash-system interface characteristics.
typedef struct _FLASH_SYSINTERFACE_INFO
{
	UCHAR VccMinProgV;				// Vcc logic supply minimum program/erase voltage.
	UCHAR VccMaxProgV;				// Vcc logic supply maximum program/erase voltage.
	UCHAR VppMinProgV;				// Vpp logic supply minimum program/erase voltage.
	UCHAR VppMaxProgV;				// Vpp logic supply maximum program/erase voltage.
	struct
	{
	    UCHAR SnglWordProgTO_us;	// Typical single word program time-out (in us).
	    UCHAR WriteBuffTO_us;		// Typical buffer write time-out (in us).
	    UCHAR BlockEraseTO_ms;		// Typical block erase time-out (in ms).
	    UCHAR ChipEraseTO_ms;		// Typical full-chip erase time-out (in ms).
	} Typical;
	struct
	{
	    UCHAR SnglWordProgTO_us;	// Max single word program time-out (in us).
	    UCHAR WriteBuffTO_us;		// Max buffer write time-out (in us).
	    UCHAR BlockEraseTO_ms;		// Max block erase time-out (in ms).
	    UCHAR ChipEraseTO_ms;		// Max full-chip erase time-out (in ms).
	} Max;
} FLASH_SYSINTERFACE_INFO, *PFLASH_INTERFACE_INFO;

// Flash geometry characteristics.
typedef struct _FLASH_GEOMETRY_INFO
{
	UCHAR DevSize;					// Flash size (n = 2^n bytes).
	USHORT DevInterface;			// Interface type (8/16).
	USHORT WriteBuffSize;			// Write buffer size (n = 2^n bytes).
	UCHAR NumEraseBlocks;			// Number of flash blocks in an erase region.
	USHORT NumIdentEraseBlocks;		// Number of identical-sized erase blocks (number of blocks).
	USHORT EraseRegionSize;         // Size of an erase region.
} FLASH_GEOMETRY_INFO, *PFLASH_GEOMETRY_INFO;

// All flash information.
typedef struct _FMD_FLASH_INFO
{
	ULONG BaseAddress;				// Flash base address.
	ULONG FlashLength;				// Length of flash to be managed.
	ULONG BlockSize;				// Block size (computed from CFI data).
	ULONG TotalFlashBlocks;			// Number of flash blocks.
	ULONG SectorSize;                       // Sector size
	FLASH_SYSINTERFACE_INFO SysInt;	// Flash-system interface information.
	FLASH_GEOMETRY_INFO Geometry;	// Flash geometry information.
} FMD_FLASH_INFO, *PFMD_FLASH_INFO;
#pragma pack()

#endif	//_STRATA_H_.
